<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.3.1"/>
<title>procman: Procman communications</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
  $(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td style="padding-left: 0.5em;">
   <div id="projectname">procman
   </div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.3.1 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Python&#160;API</span></a></li>
      <li>
        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
      </li>
    </ul>
  </div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Groups</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Pages</a></div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Procman communications </div>  </div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#procman_design_communication_overview">Overview</a></li>
<li class="level1"><a href="#procman_comms_deputy">Deputy</a><ul><li class="level2"><a href="#procman_comms_deputy_transmitted">Messages transmitted by deputy</a></li>
<li class="level2"><a href="#procman_comms_deputy_received">Messages received by deputy</a></li>
</ul>
</li>
<li class="level1"><a href="#procman_comms_sheriff">Sheriff</a><ul><li class="level2"><a href="#procman_comms_sheriff_transmitted">Messages transmitted by sheriff</a></li>
<li class="level2"><a href="#procman_comms_sheriff_received">Messages received by sheriff</a></li>
</ul>
</li>
<li class="level1"><a href="#procman_lcm_message_defs">Appendix - message definitions</a><ul><li class="level2"><a href="#procman_lcm_info2_t">bot_procman.info2_t</a></li>
<li class="level2"><a href="#procman_lcm_deputy_cmd2_t">bot_procman.deputy_cmd2_t</a></li>
<li class="level2"><a href="#procman_lcm_command2_t">bot_procman.command2_t</a></li>
<li class="level2"><a href="#procman_lcm_printf_t">bot_procman.printf_t</a></li>
<li class="level2"><a href="#procman_lcm_discovery_t">bot_procman.discovery_t</a></li>
</ul>
</li>
</ul>
</div>
<div class="textblock"><p>This page describes the <a href="http://lcm.googlecode.com">LCM</a> messages transmitted by the Procman sheriffs and deputies. Together, the LCM messages define the Procman communications protocol.</p>
<h1><a class="anchor" id="procman_design_communication_overview"></a>
Overview</h1>
<p>Sheriffs and deputies communicate by transmitting <a href="http://lcm.googlecode.com">LCM</a> messages to each other. Deputies periodically (1 Hz) transmit their current status, which includes:</p>
<ul>
<li>A listing of each command managed by the deputy and. For each command:<ul>
<li>Whether the command is running.</li>
<li>The OS-assigned process ID of the command, if it's running.</li>
<li>How much CPU and memory are used by the command.</li>
<li>Which group the command is in.</li>
</ul>
</li>
</ul>
<p>In addition to the deputy state, each deputy also captures the standard output and standard error for each running command, and transmits the output over LCM.</p>
<p>Sheriffs transmit the desired state for each deputy. For each deputy, the sheriff periodically (1 Hz) transmits a message containing:</p>
<ul>
<li>A listing of all commands the deputy <em>should</em> be managing and the desired state for each command:<ul>
<li>If the command should be running, stopped, or restarted</li>
<li>The program to run, command line arguments, and environment variables.</li>
<li>Which group the command should be in.</li>
<li>If the command should be automatically restarted if/when it terminates.</li>
</ul>
</li>
</ul>
<p>The communications protocol is stateless by design: every message transmitted from a sheriff to the deputy contains the entire desired state of the deputy. Similarly, every message transmitted by a deputy contains its entire internal state. This stateless protocol has a few key features:</p>
<ul>
<li>The entire system is robust to communication dropouts. If a deputy stops receiving messages from the sheriff, the deputy simply continues carrying out its last orders.</li>
<li>When the sheriff starts up, it seamlessly picks up the entire state of the system as it receives updates from each deputy. Deputies are unaffected by a sheriff starting up until the sheriff begins transmitting orders.</li>
<li>A sheriff in observer mode (see above) can pick up the state of the system simply by receiving deputy messages and not transmitting anything.</li>
</ul>
<p>The full communications protocol, including the LCM message definitions, is described here:</p>
<ul>
<li>procman_lcm_messages</li>
</ul>
<h1><a class="anchor" id="procman_comms_deputy"></a>
Deputy</h1>
<h2><a class="anchor" id="procman_comms_deputy_transmitted"></a>
Messages transmitted by deputy</h2>
<p>The deputy transmits the following messages:</p>
<table class="doxtable">
<tr>
<th>LCM Channel </th><th>Message type </th><th>Description</th></tr>
<tr>
<td><code>PMD_INFO2</code> </td><td>bot_procman.info2_t </td><td>Summarizes the state of all commands managed by a deputy. Transmitted at 1 Hz or when a command status changes. </td></tr>
<tr>
<td><code>PMD_PRINTF</code> </td><td>bot_procman.printf_t </td><td>Published when a hosted command generates output to stdout or stderr, and contains the output produced by the command. </td></tr>
<tr>
<td><code>PMD_DISCOVER</code> </td><td>bot_procman.discovery_t </td><td>Published to check for conflicting deputies with the same ID. Published when a deputy first starts up. </td></tr>
</table>
<h2><a class="anchor" id="procman_comms_deputy_received"></a>
Messages received by deputy</h2>
<p>The deputy subscribes to the following messages:</p>
<table class="doxtable">
<tr>
<th>LCM Channel </th><th>Message type </th><th>Description</th></tr>
<tr>
<td><code>PMD_DISOCVER</code> </td><td>bot_procman.discovery_t </td><td>When received, the deputy replies by transmitting its state on <code>PMD_INFO2</code>. </td></tr>
<tr>
<td><code>PMD_ORDERS2</code> </td><td>bot_procman.orders2_t </td><td>When received, the deputy checks if the orders are targeted for it. If not, or if the timestamp on the orders differs significantly from the deputy's system clock, then it ignores the message. Otherwise, the deputy modifies its state to achieve the state indicated by the orders. This may involve creating, starting, and stopping commands. </td></tr>
</table>
<h1><a class="anchor" id="procman_comms_sheriff"></a>
Sheriff</h1>
<h2><a class="anchor" id="procman_comms_sheriff_transmitted"></a>
Messages transmitted by sheriff</h2>
<table class="doxtable">
<tr>
<th>LCM Channel </th><th>Message type </th><th>Description</th></tr>
<tr>
<td><code>PMD_ORDERS2</code> </td><td>bot_procman.orders2_t </td><td>Commands a deputy. Each orders message contains the desired state of all commands managed by a single deputy. To command multiple deputies, the sheriff sends one orders message to each deputy. Transmitted at 1 Hz or when a command's desired status changes. </td></tr>
<tr>
<td><code>PMD_DISCOVER</code> </td><td>bot_procman.discovery_t </td><td>Published by a sheriff to discover deputies when the sheriff first starts up. </td></tr>
</table>
<h2><a class="anchor" id="procman_comms_sheriff_received"></a>
Messages received by sheriff</h2>
<table class="doxtable">
<tr>
<th>LCM Channel </th><th>Message type </th><th>Description</th></tr>
<tr>
<td><code>PMD_INFO2</code> </td><td>bot_procman.info2_t </td><td>When received, the sheriff updates its internal representation of a deputy's actual state. </td></tr>
<tr>
<td><code>PMD_PRINTF</code> </td><td>bot_procman.printf_t </td><td>Contains the console output produced by a deputy-managed command. When received, the sheriff may display a command's output to the user. Subscribing to this channel is optional for a sheriff. </td></tr>
</table>
<h1><a class="anchor" id="procman_lcm_message_defs"></a>
Appendix - message definitions</h1>
<h2><a class="anchor" id="procman_lcm_info2_t"></a>
bot_procman.info2_t</h2>
<div class="fragment"><div class="line"><span class="keyword">package </span>bot_procman;</div>
<div class="line"></div>
<div class="line"><span class="comment">/*</span></div>
<div class="line"><span class="comment">   message sent by a procman deputy, primarily intended for the procman</span></div>
<div class="line"><span class="comment">   sheriff.  informs the sheriff of the status of processes running on the</span></div>
<div class="line"><span class="comment">   host managed by the deputy.</span></div>
<div class="line"><span class="comment">*/</span></div>
<div class="line"></div>
<div class="line"><span class="keyword">struct </span>info2_t {</div>
<div class="line">    int64_t utime;</div>
<div class="line">    <span class="keywordtype">string</span> host;</div>
<div class="line"></div>
<div class="line">    <span class="comment">// [0, 1]</span></div>
<div class="line">    <span class="keywordtype">float</span> cpu_load;</div>
<div class="line"></div>
<div class="line">    int64_t phys_mem_total_bytes;</div>
<div class="line">    int64_t phys_mem_free_bytes;</div>
<div class="line">    int64_t swap_total_bytes;</div>
<div class="line">    int64_t swap_free_bytes;</div>
<div class="line"></div>
<div class="line">    int32_t ncmds;</div>
<div class="line">    deputy_cmd2_t cmds[ncmds];</div>
<div class="line"></div>
<div class="line">    int32_t num_options;</div>
<div class="line">    <span class="keywordtype">string</span> option_names[num_options];</div>
<div class="line">    <span class="keywordtype">string</span> option_values[num_options];</div>
<div class="line">}</div>
</div><!-- fragment --><h2><a class="anchor" id="procman_lcm_deputy_cmd2_t"></a>
bot_procman.deputy_cmd2_t</h2>
<div class="fragment"><div class="line"><span class="keyword">package </span>bot_procman;</div>
<div class="line"></div>
<div class="line"><span class="comment">/* describes the state of a command managed by the procman sheriff/deputy</span></div>
<div class="line"><span class="comment"> */</span></div>
<div class="line"></div>
<div class="line"><span class="keyword">struct </span>deputy_cmd2_t {</div>
<div class="line"></div>
<div class="line">    <span class="comment">// The command to execute.</span></div>
<div class="line">    command2_t cmd;</div>
<div class="line"></div>
<div class="line">    <span class="comment">// If the command is running, then this is the pid if not, then this is</span></div>
<div class="line">    <span class="comment">// zero.</span></div>
<div class="line">    int32_t pid;</div>
<div class="line"></div>
<div class="line">    <span class="comment">// an ID for the run instance</span></div>
<div class="line">    int32_t actual_runid;</div>
<div class="line"></div>
<div class="line">    <span class="comment">// the last exit code</span></div>
<div class="line">    int32_t exit_code;</div>
<div class="line"></div>
<div class="line">    <span class="comment">// [0, 1]</span></div>
<div class="line">    <span class="keywordtype">float</span> cpu_usage;</div>
<div class="line"></div>
<div class="line">    <span class="comment">// total virtual memory used by the process</span></div>
<div class="line">    int64_t mem_vsize_bytes;</div>
<div class="line"></div>
<div class="line">    <span class="comment">// total physical memory used by the process</span></div>
<div class="line">    int64_t mem_rss_bytes;</div>
<div class="line"></div>
<div class="line">    <span class="comment">// assigned by the sheriff, identifies the command</span></div>
<div class="line">    int32_t sheriff_id;</div>
<div class="line">}</div>
</div><!-- fragment --><h2><a class="anchor" id="procman_lcm_command2_t"></a>
bot_procman.command2_t</h2>
<div class="fragment"><div class="line"><span class="keyword">package </span>bot_procman;</div>
<div class="line"></div>
<div class="line"><span class="keyword">struct </span>command2_t {</div>
<div class="line">    <span class="comment">// Executable string</span></div>
<div class="line">    <span class="keywordtype">string</span> exec_str;</div>
<div class="line"></div>
<div class="line">    <span class="keywordtype">string</span> command_name;</div>
<div class="line"></div>
<div class="line">    <span class="keywordtype">string</span> group;</div>
<div class="line"></div>
<div class="line">    <span class="keywordtype">boolean</span> auto_respawn;</div>
<div class="line"></div>
<div class="line">    int8_t stop_signal;</div>
<div class="line"></div>
<div class="line">    <span class="keywordtype">float</span> stop_time_allowed;</div>
<div class="line"></div>
<div class="line">    int32_t num_options;</div>
<div class="line"></div>
<div class="line">    <span class="keywordtype">string</span> option_names[num_options];</div>
<div class="line"></div>
<div class="line">    <span class="keywordtype">string</span> option_values[num_options];</div>
<div class="line">}</div>
<div class="line"></div>
</div><!-- fragment --><h2><a class="anchor" id="procman_lcm_printf_t"></a>
bot_procman.printf_t</h2>
<div class="fragment"><div class="line"><span class="keyword">package </span>bot_procman;</div>
<div class="line"></div>
<div class="line"><span class="comment">/* message sent by a procman deputy when a child process writes something to</span></div>
<div class="line"><span class="comment"> * its stdout/stderr fd.  this message contains the contents of that write</span></div>
<div class="line"><span class="comment"> * (usually a printf)</span></div>
<div class="line"><span class="comment"> * also sent when the deputy itself has something to say.</span></div>
<div class="line"><span class="comment"> */</span></div>
<div class="line"></div>
<div class="line"><span class="keyword">struct </span>printf_t {</div>
<div class="line">    int64_t utime;</div>
<div class="line">    <span class="keywordtype">string</span> deputy_name;</div>
<div class="line"></div>
<div class="line">    <span class="comment">// sheriff-assigned id of the child process.  0 if generated by the deputy</span></div>
<div class="line">    int32_t sheriff_id;    </div>
<div class="line"></div>
<div class="line">    <span class="keywordtype">string</span> text;</div>
<div class="line">}</div>
</div><!-- fragment --><h2><a class="anchor" id="procman_lcm_discovery_t"></a>
bot_procman.discovery_t</h2>
<div class="fragment"><div class="line"><span class="keyword">package </span>bot_procman;</div>
<div class="line"></div>
<div class="line"><span class="comment">/*</span></div>
<div class="line"><span class="comment">   message sent by a procman deputy or sheriff to discover other deputies and</span></div>
<div class="line"><span class="comment">   sheriffs on the network.</span></div>
<div class="line"><span class="comment">*/</span></div>
<div class="line"></div>
<div class="line"><span class="keyword">struct </span>discovery_t {</div>
<div class="line">    int64_t utime;</div>
<div class="line">    <span class="keywordtype">string</span> host;</div>
<div class="line">    int64_t nonce;</div>
<div class="line">}</div>
</div><!-- fragment --><p> bot_procman.discover_t </p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Wed Sep 18 2013 23:53:50 for procman by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.3.1
</small></address>
</body>
</html>
